/*
 * 版权所有 (c) 2022-2099 TBIT。保留所有权利。
 */

package com.tbit.main.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.tbit.main.controller.interceptor.LoginUserContextHolder;
import com.tbit.main.dao.core.AccountUserAlarmDao;
import com.tbit.main.dao.core.AccountUserAlarmItemDao;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.AccountUserAlarm;
import com.tbit.main.pojo.AccountUserAlarmItem;
import com.tbit.main.pojo.VO.AccountUserAlarmAddReqVO;
import com.tbit.main.pojo.VO.AccountUserAlarmQueryReqVO;
import com.tbit.main.pojo.VO.AccountUserAlarmRespVO;
import com.tbit.main.pojo.VO.AccountUserAlarmUpdateReqVO;
import com.tbit.main.pojo.bo.AccountUserAlarmItemBO;
import com.tbit.main.service.AccountUserAlarmService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author <a href="mailto:li.yao@tbit.com.cn">yao</a>
 * @version 4.1.0
 * @since 2024/7/11 14:14
 */
@Service
@Validated
public class AccountUserAlarmServiceImpl implements AccountUserAlarmService {

    @Resource
    private AccountUserAlarmDao accountUserAlarmDao;

    @Resource
    private AccountUserAlarmItemDao accountUserAlarmItemDao;

    @Override
    public void addUserAlarm(AccountUserAlarmAddReqVO reqVO) {
        checkPhoneExistsThrow(reqVO.getPhone());

        reqVO.setCreator(LoginUserContextHolder.getLoginUser().getUserName());
        accountUserAlarmDao.insertUserAlarm(reqVO);
    }

    private void checkPhoneExistsThrow(String phone) {
        if (accountUserAlarmDao.selectCountByPhone(phone) > 0) {
            throw new BaseException("AccountUser.phone.repetition");
        }
    }

    @Override
    public void deleteUserAlarm(Long id) {
        accountUserAlarmDao.deleteById(id);
    }

    @Override
    public void updateUserAlarmItem(AccountUserAlarmUpdateReqVO reqVO) {
        Long accountUserAlarmId = reqVO.getId();
        AccountUserAlarm accountUserAlarm = accountUserAlarmDao.selectById(accountUserAlarmId);
        if (accountUserAlarm == null) {
            throw new BaseException("预警账号不存在");
        }

        accountUserAlarmItemDao.deleteByAccountUserAlarmId(accountUserAlarmId);
        List<Integer> alarmItem = reqVO.getAlarmItem();
        if (CollUtil.isNotEmpty(alarmItem)) {
            accountUserAlarmItemDao.insertBatch(AccountUserAlarmItemBO.createAlarmItemBO(accountUserAlarm.getAccountId(), accountUserAlarmId, alarmItem));
        }
        reqVO.setUpdater(LoginUserContextHolder.getLoginUser().getUserName());
        accountUserAlarmDao.updateById(reqVO);
    }

    @Override
    public AccountUserAlarmRespVO getById(Long id) {
        AccountUserAlarm accountUserAlarm = accountUserAlarmDao.selectById(id);
        AccountUserAlarmRespVO respVO = new AccountUserAlarmRespVO();
        BeanUtils.copyProperties(accountUserAlarm, respVO);

        List<AccountUserAlarmItem> accountUserAlarmItem = accountUserAlarmItemDao.selectByAccountUserAlarmId(id);
        List<Integer> alarmItem = accountUserAlarmItem.stream().map(AccountUserAlarmItem::getAlarmType).collect(Collectors.toList());

        respVO.setAlarmItem(alarmItem);
        return respVO;
    }

    @Override
    public List<AccountUserAlarmRespVO> getUserAlarmList(AccountUserAlarmQueryReqVO reqVO) {
        List<AccountUserAlarm> accountUserAlarms = accountUserAlarmDao.selectUserAlarmList(reqVO);

        Map<Integer, List<Integer>> map = buildAccountUserAlarmItemMap(reqVO.getAccountId());

        return accountUserAlarms.stream().map(accountUserAlarm -> {
            AccountUserAlarmRespVO respVO = new AccountUserAlarmRespVO();
            BeanUtils.copyProperties(accountUserAlarm, respVO);
            respVO.setAlarmItem(map.get(accountUserAlarm.getId()));
            return respVO;
        }).collect(Collectors.toList());
    }

    @Override
    public List<AccountUserAlarmRespVO> getByAccountId(Integer accountId) {
        List<AccountUserAlarm> accountUserAlarms = accountUserAlarmDao.selectByAccountId(accountId);

        Map<Integer, List<Integer>> map = buildAccountUserAlarmItemMap(accountId);

        return accountUserAlarms.stream().map(accountUserAlarm -> {
            AccountUserAlarmRespVO respVO = new AccountUserAlarmRespVO();
            BeanUtils.copyProperties(accountUserAlarm, respVO);
            respVO.setAlarmItem(map.get(accountUserAlarm.getId()));
            return respVO;
        }).collect(Collectors.toList());
    }

    private Map<Integer, List<Integer>> buildAccountUserAlarmItemMap(Integer accountId) {
        List<AccountUserAlarmItem> accountUserAlarmItems = accountUserAlarmItemDao.selectByAccountId(accountId);

        return accountUserAlarmItems.stream()
                .collect(Collectors.groupingBy(
                        AccountUserAlarmItem::getAccountUserAlarmId,
                        Collectors.mapping(AccountUserAlarmItem::getAlarmType, Collectors.toList())
                ));
    }
}
